#include "Common.h"
#include "ShortestPath.h"
#include <string>
#include <string.h>
#include <fstream>

#define INF 2147483647

class compare {
  public:
    bool operator() (const char* a, const char* b) {
        return (strcoll(a, b) < 0);
    }
};

void ShortestPathInit(int argc, char* argv[], Master<int, int,int> &master){
    if (argc != 4) {
        printf ("Usage: %s <num_procs> <partition_mode:s,e,a,l> <input_file>\n", argv[0]);
        exit (1);
    }

    printf("[ShortestPathInit] parsing ShortestPath input: %s\n", argv[3]);
//    FILE* input = fopen(argv[3], "rt");
//
//    int ret;
//    int num_nodes = 0;
//    ret = fscanf(input, "%d\n", &num_nodes);

    map <char *, ShortestPathVertex*, compare> nodeMap;
    ifstream infile;
    infile.open(argv[3], ifstream::in);
    while (!infile.eof()) {
        string line;
        getline (infile, line);
        if (line.find('#') != string::npos) continue;
        if (line.size() == 0) break;

        char *node1 = new char [100];
        char *node2 = new char [100];
        sscanf(line.c_str(), "%s\t%s\n", node1, node2);
        if (nodeMap.find(node1) == nodeMap.end()) {
            ShortestPathVertex *vertex = new ShortestPathVertex(INF, &master);
            nodeMap.insert(make_pair(node1, vertex));
            PRINTF("Insert node %s with id %d\n", node1, vertex->vertex_id());
        }
        else {
            delete [] node1;
        }
        if (nodeMap.find(node2) == nodeMap.end()) {
            ShortestPathVertex *vertex = new ShortestPathVertex(INF, &master);
            nodeMap.insert(make_pair(node2, vertex));
            PRINTF("Insert node %s with id %d\n", node2, vertex->vertex_id());
        }
        else {
            delete [] node2;
        }
    }
    infile.close();

//    printf("[ShortestPathInit] file opened: %d nodes all together\n", num_nodes);
//    for(int i = 0; i < num_nodes; i++) {
//        // vertex will be added to master when constructed
//        ShortestPathVertex *vertex = new ShortestPathVertex(INF, &master);
//        int num_links = 0;
//        ret = fscanf(input, "%d ", &num_links);
//        for(int j = 0; j < num_links; j++) {
//            int dest = -1;
//            int edge_value = -1;
//            ret = fscanf(input, "%d %d ", &dest, &edge_value);
//            vertex->addOutEdge(dest, edge_value);
//        }
//        ret = fscanf(input, "\n");
//    }
//    fclose(input);
    infile.open(argv[3], ifstream::in);
    while (!infile.eof()) {
        string line;
        char node1[100];
        char node2[100];
        getline (infile, line);
        if (line.find('#') != string::npos) continue;
        if (line.size() == 0) break;

        sscanf(line.c_str(), "%s\t%s\n", node1, node2);
        if (nodeMap.find(node1) == nodeMap.end()) {
            printf ("Node %s not found\n", node1);
            exit(1);
        }
        ShortestPathVertex *homeVertex = nodeMap.find(node1)->second;
        homeVertex->addOutEdge(nodeMap.find(node2)->second->vertex_id(), 1);
        PRINTF("Add edge from node %s (id = %d) to node %s (id = %d)\n", node1, homeVertex->vertex_id(), node2, nodeMap.find(node2)->second->vertex_id());
    }
    infile.close();

    // deallocate memory
    map <char *, ShortestPathVertex *, compare>::iterator itr;
    for (itr = nodeMap.begin(); itr != nodeMap.end(); itr++) {
        delete [] itr->first;
    }

    printf("[ShortestPathInit] finished input parsing\n");
}
